<template>
  <div id="animate-container">
    <!-- 动画容器 -->
  </div>
</template>

<script>
import { Circle as CircleStyle, Fill, Stroke, Style, Text } from "ol/style";
import Icon from "ol/style/Icon";

import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import { transform, getTransform } from "ol/proj"; // 坐标转换
// import * as olProj from 'ol/proj'
import Feature from "ol/Feature";
import Point from "ol/geom/Point";
import LineString from "ol/geom/LineString";
import Polygon from "ol/geom/Polygon";
import Circle from "ol/geom/Circle";

// 引入功能组件
import mapStyle from "../common/mapStyle.js"; // 样式功能
import linePart from "./linePart.js";
import animMath from "./animMath.js";
import animSprite from "./animSprite.js";
import animSocet from "./animSocket.js";
import { truncate } from "@turf/turf";

export default {
  mixins: [mapStyle, linePart, animMath, animSprite, animSocet],
  data() {
    return {
      oMap: null, // 地图对象
      sSRS: "EPSG:4326", // 空间参照系（Spatial Reference System)；表示数据的坐标系，和地图用的RCS不是同一个
      sMapRCS: null, // 当前地图使用的参考坐标系，配置文件中也有 this.oMap.getView().getProjection().getCode()
      animLayer: null, // 动画层，所有操作在此组件中完成，故放此处
      animSource: null, // 动画层资源
      // animStyleList: [], // 样式统一保存到全局的样式列表中；--动画层样式关联数组；保存animLayer层所有公用样式
      aSpritesList: [], // 精灵列表--每个精灵一个元素。渲染时依次循环处理，调用自己对应的绘制方法！-- 关联数组 用id做索引？
      aUnArray: [], // 用来校验唯一值的关联数组，如：记录 地址：[lon,lat]
      bAnimating: false, // 动画标志位（动画是否启动！）用于动画的启停； 实时定位不受此标志影响
      aStyleList: null, // 父类定义的样式列表，POI需要使用，所以初始化时引入！
      sIconType: "standard", // 引入mapStyle.js会混入此变量，cardMap也会引入此变量；两者又相同。（会有问题--变更后要重新创建动画层）
      animSelected: null, // 动画层中选中的对象 {id：当前选中的featureID，style: 选中feature原来的样式}
    };
  },
  watch: {
    // watch
  },
  mounted() {
    // mounted
  },
  methods: {
    /**
     * @description 字符路径名称获取路径及文件名
     * @param {Array} sPath 待处理的文件路径字符串
     * @return [sFilePath, sFileName]
     */
    getFilePathName(sPath) {
      const pos1 = sPath.lastIndexOf("/");
      const pos2 = sPath.lastIndexOf("\\");
      var pos = Math.max(pos1, pos2);
      if (pos < 0) {
        return ["", sPath];
      } else {
        const sFilePath = sPath.substring(0, pos);
        const sFileNamw = sPath.substring(pos + 1);
        return [sFilePath, sFileNamw];
      }
    },
    /**
     * @description 清空关联数组
     * @param {Array} oArray 样式列表数组
     * @return
     */
    clearAssociateArray(oArray) {
      console.log(oArray);
      const nLen = Object.keys(oArray).length;
      oArray.splice(0, nLen);
    },

    /**
     * @description 返回关联数组元素个数
     * @param {Array} oArray 样式列表数组
     * @return {Number} 数组元素个数
     */
    getStyleNum(oArray) {
      return Object.keys(oArray).length;
    },

    /**
     * @description 通过key获取关联数组元素
     * @param sName 要获取元素的key值；
     * @param oArray {Array} 关联数组
     * @return oStyle {Object}返回获取到的样式或null（没有指定的样式）
     */
    getAssociateArrayValByName(sName, oArray) {
      if (oArray[sName]) {
        return oArray[sName];
      } else {
        return null;
      }
    },

    /**
     * @description 从样关联数组中删除指定的元素
     * @param sName {String}样式名称； oArray {Array} 样式列表数组
     * @return ？返回删除的地图样式？
     */
    delAssociateArrayByName(sName, oArray) {
      if (oArray[sName]) {
        delete oArray[sName];
      }
    },

    /**
     * @description 检查动画层是否存在
     * @return {boolean} 返回true或false 表示动画层是否存在
     */
    hasAnimLayer() {
      if (this.animLayer) {
        return true;
      } else {
        return false;
      }
    },

    /**
     * @description 初始化动画图层(创建vectorLayer)并添加到地图中显示
     * @param oParentMap {Object} 地图实例，新建的POI层添加到此地图中;(父组件提供)
     * @return null
     */
    initAnimLayer(oParentMap, aMapStyleList, sMapIconType) {
      this.oMap = oParentMap;
      this.aStyleList = aMapStyleList || this.$parent.aStyleList; // 不使用父类统一的样式列表，动画层结束后可以直接释放动画层样式animStyle[关联数组]
      this.sIconType = sMapIconType || this.$parent.sIconType; // 使用的图标样式（标准，卡通，3d等）
      // 创建动画层资源（有则清空，没有则创建）
      if (this.animSource) {
        this.animSource.clear();
      } else {
        this.animSource = new VectorSource(); // ol.source.Vector()
      }
      // 创建动画层
      this.animLayer = new VectorLayer({
        // ol.layer.Vector
        source: this.animSource,
      });
      this.animLayer.set("name", "animLayer");
      this.oMap.addLayer(this.animLayer);
      // 调整层级关系--从15更为70
      this.animLayer.setZIndex(70);
      // 设置参考坐标系,如：EPSG:3857
      if (!this.sMapRCS) {
        this.sMapRCS = this.$parent.conf.RCS;
        if (!this.sMapRCS) {
          this.sMapRCS = this.oMap.getView().getProjection().getCode();
        }
      }
    },

    /**
     * @description 销毁动画层；没有使用动画时，可以删除此层
     * @param null
     * @return null
     */
    destroyAnimLayer() {
      if (this.aSpritesList.length > 0) {
        this.aSpritesList.splice(0, this.aSpritesList.length); // 清空精灵数组
      }
      // 清除动画层样式数组--使用父级的样式数组了
      // this.clearAssociateArray(this.animStyle) // --animStyleList
      // 清空唯一校验关联数组
      this.clearAssociateArray(this.aUnArray);
      // 删除动画层
      if (this.animLayer) {
        // const animSource = this.animLayer.getSource()
        this.animSource.clear();
        this.oMap.removeLayer(this.animLayer);
      }
    },

    /**
     * @description 清空动画数据
     * @param  null
     * @return null
     */
    clearAnimData() {
      if (this.aSpritesList.length > 0) {
        this.aSpritesList.splice(0, this.aSpritesList.length); // 清空精灵数组
      }
      // 清除动画层样式数组--使用父级的样式数组了
      // this.clearAssociateArray(this.animStyle) // --animStyleList
      // 清空唯一校验关联数组
      this.clearAssociateArray(this.aUnArray);
      // 清空空话数据
      if (this.animLayer) {
        // 删除资源中的数据
        this.animSource.clear();
      }
      // 动画中是否使用了气泡和闪烁?
    },

    /**
     * @description 清空动画图层中的全部数据
     * @param  null
     * @return null
     */
    clearAllData() {
      this.clearAnimData();
      // 清除气泡及详情信息（需要相应模块支持！）
      // 清空详情信息
      // 删除热力图 和 动画层数据？
    },

    /**
     * @description 获取动画层的样式
     * @param oStyleData {Object} 包含样式数据的对象，获取数据中的properties
     * @return {Object} 获取到的样式
     */
    getAnimStyle(oStyleData) {
      // 获取样式id--名称
      let sStyleID = oStyleData.styleid;
      if (sStyleID) {
        // 如果有ID名称，使用它来
        if (this.aStyleList[sStyleID]) {
          return this.aStyleList[sStyleID]; // 样式已经存在，直接返回使用
        } else {
          // 创建样式
          this.addStyle2StyleList(oStyleData, sStyleID, this.aStyleList); // mapStyle.js (样式数据，样式名称，样式列表)
          return this.aStyleList[sStyleID];
        }
      } else if (oStyleData.icon) {
        // 数据中没有styleid，但有icon类型有样式列表
        sStyleID = oStyleData.icon.src;
        // 如果样式在样式列表中不存在，需要创建样式
        if (this.aStyleList[sStyleID]) {
          // 样式已经存在，直接返回使用 // oStyleData.icon.src
          return this.aStyleList[sStyleID]; // oStyleData.icon.src
        } else {
          // 创建样式
          this.addStyle2StyleList(oStyleData, sStyleID, this.aStyleList); // mapStyle.js (样式数据，样式名称，样式列表)  // oStyleData.icon.src
          return this.aStyleList[sStyleID]; // oStyleData.icon.src
        }
      } else {
        // 如果样式名称（sStyleID）和icon类型都不存在，不放人样式列表
        const oNewStyle = this.createStyle(oStyleData);
        // instStyle2StyleList (oNewStyle, sStyleID, this.aStyleList)
        return oNewStyle;
      }
    },

    /**
     * @description 显示动画数据
     * @param oResData {Object} 获取到的动画数据
     * @return
     */
    showAnimData(oResData) {
      if (!oResData || JSON.stringify(oResData) === "{}") {
        return; // 没有数据作处理
      }
      console.log(oResData);
      const nDataTypeNum = oResData.length;
      for (let i = 0; i < nDataTypeNum; i++) {
        const oData = oResData[i]; // 获取一类数据
        if (oData.style && !(JSON.stringify(oData.style) === "{}")) {
          // 如果此类数据开头提供了样式Style，可预先导入；操作与POI相同
          // 如果样式在样式列表中不存在，需要创建样式style':{ 'icon': {'sStyleID':'styleName', 'src': 'X01气泡'}  }
          this.getAnimStyle(oData.style);
        }
        // 绘制图标
        // const oGeoJson = oData.geojsonfeatures // 一个数据类型的geojson数据信息
        // if (oGeoJson.type === 'FeatureCollection') { // 处理Feature集合
        //   console.log(oGeoJson)
        //   this.readFeatures(oGeoJson)
        // }
        const dataType = oResData[i].dataType;
        console.log(dataType);
        if (dataType === "roadx") {
          // console.log('123=====================================')
          for (let j = 0; j < oData.geojsonfeatures.features.length; j++) {
            const oGeoJson = oData.geojsonfeatures.features[j];
            console.log(oGeoJson);
            this.drawRoadLine(oGeoJson);
          }
        }
        // 绘制由两点确定的曲线
        if (dataType === "simplecurve") {
          for (let j = 0; j < oData.geojsonfeatures.features.length; j++) {
            const oGeoJson = oData.geojsonfeatures.features[j];
            console.log(oGeoJson);
            this.drawCurveOfTwoPoint(oGeoJson);
          }
        }
        // 绘制精灵数据
        if (dataType === "sprite") {
          for (let j = 0; j < oData.geojsonfeatures.features.length; j++) {
            const oGeoJson = oData.geojsonfeatures.features[j];
            console.log(oGeoJson);
            this.drawAnimSprite(oGeoJson);
          }
        }
        // 绘制关系图谱连线
        if (dataType === "relation") {
          for (let j = 0; j < oData.geojsonfeatures.features.length; j++) {
            const oGeoJson = oData.geojsonfeatures.features[j];
            console.log(oGeoJson);
            this.drawRelationLine(oGeoJson);
          }
        }
      }
    },
    // 当前方法
  },
};
</script>

<style lang="scss">
#animate-container {
  height: 100%;
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
}

.anim-baseinfo {
  position: absolute;
  left: -100px;
  bottom: 12px;
  background-color: #fff;
  border-radius: 0.3rem;
  min-width: 200px;
  padding: 3px 5px;
  overflow: hidden;
  z-index: 4;
  border: 1px solid rgba(0, 0, 0, 0.2);
  font-size: 0.875rem;
  font-style: normal;
  font-weight: 400;
}

// 选中边框样式
.selectedDiv {
  border: 2px solid red;
}

// 添加闪烁样式
.css_animation {
  height: 50px;
  width: 50px;
  border-radius: 25px;
  background: rgba(255, 0, 0, 0.9);
  transform: scale(0);
  animation: cssflash 3s;
  animation-iteration-count: infinite;
}

.marker {
  background-position: center center;
  width: 20px;
  height: 20px;
  display: flex;
  display: -webkit-flex;
  align-items: center;
  justify-content: center;
}

.marker p {
  background-color: rgba(250, 0, 0, 0.2);
  width: 10px;
  height: 10px;
  border-radius: 50%;
  animation: myfirst 1.4s infinite;
  box-shadow: 0px 0px 2px #f00;

  @keyframes cssflash {
    to {
      transform: scale(2);
      background: rgba(0, 0, 0, 0);
    }
  }

  @keyframes myfirst {
    to {
      transform: scale(8);
    }
  }
}
</style>
